package leetcode;

import org.junit.Test;

import java.util.HashMap;
import java.util.Map;

/**
 * @author: feiwang_6
 * @create: 2020/4/17 6:45
 * @description:
 */
public class StrConvertnNumber {
    @Test
    public void testMath() {
        System.out.println(myAtoi("-21474836481"));
        System.out.println(myAtoi1("-21474836481"));
        System.out.println(myAtoi3("-21474836481"));
    }

    public int myAtoi(String str) {
        int result = 0;
        int i = 0, flag = 1;
        int iMax = Integer.MAX_VALUE / 10;
        while (i < str.length() && str.charAt(i) == ' ')
            i++;
        //符号位
        if (i < str.length() && str.charAt(i) == '-') {
            flag = -1;
        }
        if (i < str.length() && (str.charAt(i) == '-' || str.charAt(i) == '+')) {
            i++;
        }
        //寻找数字
        while (i < str.length()) {
            if (!(str.charAt(i) >= '0' && str.charAt(i) <= '9')) {
                break;
            }
            if (result > iMax || (result == iMax && str.charAt(i) > '7')) {
                return flag > 0 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
            }
            result = result * 10 + (str.charAt(i) - '0');
            i++;
        }
        return result * flag;
    }

    public int myAtoi1(String str) {
        long result = 0;
        int i = 0;
        boolean zFlag = true;
        while (i < str.length() && str.charAt(i) == ' ')
            i++;
        if (i == str.length()) {
            return 0;
        }
        //符号位
        if (str.charAt(i) == '-') {
            zFlag = false;
            i++;
        } else if (str.charAt(i) == '+') {
            i++;
        } else if (!Character.isDigit(str.charAt(i))) {
            return 0;
        }
        //寻找数字
        while (i < str.length()) {
            if (!Character.isDigit(str.charAt(i))) {
                break;
            }
            int temp = str.charAt(i) - '0';
            result = result * 10 + temp;
            if (result > Integer.MAX_VALUE) {
                return zFlag ? Integer.MAX_VALUE : Integer.MIN_VALUE;
            }
            i++;
        }
        return zFlag ? (int) result : (int)-result;
    }


    /**
     * 有限自动机编程
     * @param str
     * @return
     */
    public int myAtoi3(String str) {
        Automaton automaton = new Automaton();
        char[] c = str.toCharArray();
        for (char ch : c) {
            automaton.get(ch);
        }
        return automaton.sign * ((int) automaton.ans);
    }
    
    class Automaton {
        final String START = "start";
        final String SIGNED = "signed";
        final String IN_NUM = "in_number";
        final String END = "end";
        String state = START;
        Map<String, String[]> map;
        public int sign = 1;
        public long ans = 0;

        public Automaton() {
            map = new HashMap<>();
            map.put(START, new String[]{START, SIGNED, IN_NUM, END});
            map.put(SIGNED, new String[]{END, END, IN_NUM, END});
            map.put(IN_NUM, new String[]{END, END, IN_NUM, END});
            map.put(END, new String[]{END, END, END, END});
        }

        public int get_col(char c) {
            if (c == ' ') return 0;
            if (c == '+' || c == '-') return 1;
            if (c >= '0' && c <= '9') return 2;
            return 3;
        }

        public void get(char c) {
            state = map.get(state)[get_col(c)];
            if (state.equals(IN_NUM)) {
                ans = ans * 10 + c - '0';
                if(ans > Integer.MAX_VALUE){
                    ans = (sign == 1 ? Integer.MAX_VALUE : -(long)Integer.MIN_VALUE);
                }
            } else if (state.equals(SIGNED))
                sign = c == '+' ? 1 : -1;
        }
    }
}
